package com.orm.mybatis.xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.always.ClassUtil;
import com.orm.TableInfo;
import com.orm.mybatis.orm.Mybatis;

import lombok.extern.log4j.Log4j2;

/**
 * 创建类对应的xml文件
 */
@Log4j2
public class MapperXml {
	// xml文档对象
	private static Document mapper;
	// 增删改返回的类类型
	private static final Class<?> reesultClass = int.class;

	// 创建mapper映射文件
	public static void createMapper(Class<?> classType, String path) {
		// 创建mybatis的sql和表信息
		Mybatis mybatis = new Mybatis(classType);
		TableInfo info = mybatis.getInfo();

		String className = classType.getName();
		mapper = DocumentHelper.createDocument();
		// 添加xml文件的声明
		mapper.addDocType("mapper",
				"-//mybatis.org//DTD Mapper 3.0//EN\"\n\"http://mybatis.org/dtd/mybatis-3-mapper.dtd", null);

		// 创建mapper根元素元素
		Element mapper = MapperXml.mapper.addElement("mapper");
		// 添加mapper元素的属性
		mapper.addAttribute("namespace", "");
		// 添加映射元素标签
		Element resultMap = mapper.addElement("resultMap");
		// 添加映射元素的属性
		resultMap.addAttribute("type", className);
		resultMap.addAttribute("id", "");
		// 添加主键
		Element id = resultMap.addElement("id");
		id.addAttribute("property", info.getFieldId());
		id.addAttribute("column", info.getId());
		// 类的所有属性
		List<String> columns = info.getColumn();
		List<String> fields = info.getField();
		// 遍历所有的属性
		for (int i = 0; i < columns.size(); i++) {
			Element resuletMapEle = null;
			resuletMapEle = resultMap.addElement("result");
			// 为元素添加属性
			resuletMapEle.addAttribute("property", fields.get(i));
			resuletMapEle.addAttribute("column", columns.get(i));
		}
		// 在映射文件中添加增加标签
		Element insert = mapper.addElement("insert");
		insert.addAttribute("id", "");
		insert.addAttribute("parameterType", className);
		insert.addAttribute("resultType", ClassUtil.classType(reesultClass));
		insert.addText(mybatis.insert());

		// 在映射文件中添加删除标签
		Element delete = mapper.addElement("delete");
		delete.addAttribute("id", "");
		delete.addAttribute("parameterType", info.getIdType());
		delete.addAttribute("resultType", ClassUtil.classType(reesultClass));
		delete.addText(mybatis.delete());

		// 在映射文件中添加修改的标签
		Element update = mapper.addElement("update");
		update.addAttribute("id", "");
		update.addAttribute("parameterType", info.getIdType());
		update.addAttribute("resultType", ClassUtil.classType(reesultClass));
		update.addText(mybatis.update());

		// 在映射文件中添加查询的标签
		Element select = mapper.addElement("select");
		select.addAttribute("id", "");
		select.addAttribute("resultMap", "");
		select.addText(mybatis.select(true));

		// 在映射文件中添加查询的标签
		Element selectObj = mapper.addElement("select");
		selectObj.addAttribute("id", "");
		selectObj.addAttribute("parameterType", info.getIdType());
		selectObj.addAttribute("resultType", className);
		selectObj.addText(mybatis.select(false));

		// 获取当前项目的路径
		String projectPath = System.getProperty("user.dir") + "\\src\\";
		// 判断传入的参数是否为null
		if (null != path) {
			// 以"."进行切割
			String[] paths = path.split("\\.");
			// 遍历可变参数的路径
			for (int i = 0; i < paths.length; i++) {
				projectPath += paths[i] + "\\";
			}
		}
		// xml文件的路径
		String filePath = projectPath + classType.getSimpleName() + "Dao.xml";
		// 将文档写出
		writeDocument(filePath);
		log.info("mapper映射文件 done ......");
	}

	// 将xml文档写出去
	private static void writeDocument(String path) {
		try {
			// 创建格式化流
			OutputFormat outputFormat = OutputFormat.createPrettyPrint();
			// 创建输出流
			FileOutputStream outputStream = new FileOutputStream(new File(path));
			// 创建xml输出流
			XMLWriter writer = new XMLWriter(outputStream, outputFormat);
			// 写出xml文档
			writer.write(mapper);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
